如你所见,虽然Ui不好看,但是也还凑合
本文介绍使用我如何使用godot来实现这个模型
在线使用地址:
turing-machine by xingwangzhe
项目地址:
github:
xingwangzhe/turing_machine: 图灵机模型,使用godot实现:)
gitee:
turing_machine: 图灵机模型,使用godot实现:)
为什么使用godot
实现图形化界面,有很多方法,比如说Qt什么的,但对于我个人来说,学习成本有点高了,想到之前我自己照葫芦画瓢跟着b站上视频学godot开发小游戏,效果还不错,于是就选择godot来实现了
虽然有点杀鸡用牛刀的感觉,但能够实现目的就可以 \x7e~不择手段~~:)
思路分析
本文中 text
(String)表示字符串,pos
(int)表示字符串的索引,state
(int)表示状态,retain
(String)表示保留符。
示例:单带图灵机
单带图灵机很容易抽像为字符串数组(String),那么状态转移函数就是对字符串数组进行操作.
我们拿出一个来举例
以下是主要的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
| func tur_action_2(pos:int,state:int,retain:String): $"../tag".text=" " for i in range(0, $".".text.length()): if i==pos: $"../tag".text[i]='V' else: $"../tag".text[i]='.' if (state==0): if($".".text[pos]=='a'): $".".text[pos]='X' state=1 retain='a' pos+=1 elif ($".".text[pos]=='b'): $".".text[pos]='Y' state=1 pos+=1 retain='b' $"../../Panel/VScrollBar/log".text+="\nq0->q1 [retain:"+retain+"]" elif(state==1): if($".".text[pos]=='a'||$".".text[pos]=='b'): pos+=1 $"../../Panel/VScrollBar/log".text+="\nq1->q1 [retain:"+retain+"]" elif ($".".text[pos]=='c'): pos+=1 state=2 $"../../Panel/VScrollBar/log".text+="\nq1->q2 [retain:"+retain+"]" elif(state==2): if($".".text[pos]=='X'||$".".text[pos]=='Y'): pos+=1 $"../../Panel/VScrollBar/log".text+="\nq2->q2 [retain:"+retain+"]" elif ($".".text[pos]=='a'&&retain=='a'): text[pos]='X' state=3 pos-=1 $"../../Panel/VScrollBar/log".text+="\nq2->q3 [retain:"+retain+"]" elif ($".".text[pos]=='b' && retain=='b'): text[pos]='Y' state=3 pos-=1 $"../../Panel/VScrollBar/log".text+="\nq2->q3 [retain:"+retain+"]" elif(state==3): if(text[pos]=='X'||text[pos]=='Y'): pos-=1 $"../../Panel/VScrollBar/log".text+="\nq3->q3 [retain:"+retain+"]" elif(text[pos]=='c'): state=4 pos-=1 $"../../Panel/VScrollBar/log".text+="\nq3->q4 [retain:"+retain+"]" elif(state==4): if(text[pos]=='a'||text[pos]=='b'): state=5 pos-=1 $"../../Panel/VScrollBar/log".text+="\nq4->q5 [retain:"+retain+"]" elif(text[pos]=='X'||text[pos]=='Y'): state=6 pos+=1 $"../../Panel/VScrollBar/log".text+="\nq4->q6 [retain:"+retain+"]" elif(state==5): if(text[pos]=='a'||text[pos]=='b'): pos-=1 $"../../Panel/VScrollBar/log".text+="\nq5->q5 [retain:"+retain+"]" elif(text[pos]=='X'||text[pos]=='Y'): state=0 pos+=1 $"../../Panel/VScrollBar/log".text+="\nq5->q0 [retain:"+retain+"]" elif(state==6): if(text[pos]=='X'||text[pos]=='Y'||text[pos]=='c'): pos+=1 $"../../Panel/VScrollBar/log".text+="\nq6->q6 [retain:"+retain+"]" elif(text[pos]=='B'): state=7 pos-=1 $"../../Panel/VScrollBar/log".text+="\nq6->q7 [retain:"+retain+"]" elif(state==7): if(text[pos]=='X'||text[pos]=='Y'||text[pos]=='c'): if(text[pos]=='X'): text[pos]='a' elif(text[pos]=='Y'): text[pos]='b' pos-=1 $"../../Panel/VScrollBar/log".text+="\nq7->q7 [retain:"+retain+"]" elif(text[pos]=='B'): state=8 pos+=1 $"../../Panel/VScrollBar/log".text+="\nq7->q8 [retain:"+retain+"]" elif(state==8): pos=1 state=0 $"../../Panel/VScrollBar/log".text+="\nq8->end [retain:"+retain+"]" for i in range(0, $".".text.length()): if i==pos: $"../tag".text[i]='V' else: $"../tag".text[i]='.' return [pos,state,retain]
|
看来web不识别gdscript,给python格式倒是显示了:)
状态转移函数采用的分支条件语句来写,先判断每次操作时的状态,再根据读取的字符进行判断,然后做出状态改变或者位移或者字符改变
$”../../Panel/VScrollBar/log”
这个是在godot树状结构中,取对象地址(不是机器内存的地址,而是这个对象在项目结构中的路径)的方法,确保了获取对象的唯一性
辅助方法
函数什么时候调用,怎么调用,这都是有方法的,在游戏开发领域,信号
(signal
)是一种用于实现模块或功能间通信的机制,它允许一个游戏对象对另一个游戏对象的变化做出反应,而无需相互引用。信号是一种解耦的方法,可以使得代码组织得更好、更易于管理
简单理解就是:
godot在监听事件,我按下按钮触发事件,信号连接到对象上,可以触发对象的方法。
响应式ui
懒得说了,了解前端的应该都知道
参考
东北大学计算理论ppt
Godot 文档 – master 分支 — Godot Engine (4.x) 简体中文文档
p u b l i c
2024/11/19 16:33:23 CST
L I C E N S E